var fs = require('fs')
    , http = require('http')
    , url = require('url');
var io = require('socket.io')();
var connectionList = [];
var common = require('./common');
var async = require('async');
var https = require('https');
var fs = require('fs');
var file = "config.json";
var result = JSON.parse(fs.readFileSync(file));
var APP_ID = result.APP_ID;//小程序appid  
var APP_SECRET = result.APP_SECRET;//小程序app_secret
//var redisClient = common.getRedisClient(); //暂时关闭redis验证
//common.subscribeRedis(redisclient,'chatchannel');
var rooms = {};//保存所有房间的参赛者的socketId(快速遍历本房间的所有比赛者)
var games = {};//保存所有房间的游戏状态及规则
var battles = {};//保存天梯对战玩家所在的房间
var searchingPlayers = [];//正在天梯寻找对手的玩家列表
var ladders = {};//登录天梯的玩家列表
var playerData = {};//记录玩家当日已答题列表

async.auto({
	loadQuestions: function (callback) {
		common.initPool();
		var pool = common.getPool();
		pool.getConnection(function (err, conn) {
			if (err) console.log("POOL ==> " + err);
			var pids = [];
			conn.query('SELECT * FROM answer_room',function(error, results) {
					if(error) {
			//			console.log("ClientReady Error: " + error.message);
					//	conn.end();
						return;
					}
					if(results.length > 0) {
						for (var i in results) {
							var room = results[i];
							var id = room['id'];
							//open:是否允许抢答   player:当前的答题者   allow:是否允许答题  currentIndex:当前题目的游标
							//queries:提出质疑的参赛者列表   answers:选择题当前题目回答的列表  blackList:抢答错误被屏蔽的参赛者列表
							games[id] = {begin:false,type:room['type'],mode:room['mode'],listID:room['listID'],status:room['status'],number:room['number'],open:1,player:'',points:[],blackList:[],heads:[],questions:[],currentIndex:0,allow:0,answers:{},queries:[]};
					//		console.log("创建game:"+id);
							 //判断是否需要加载题目
							if(room['listID']) {
								pids.push({id:id,listId:room['listID']});
						//		console.log("房间"+id+"加载题单:"+room['listID']);
							}
						}
				//		console.log('成功加载了'+results.length+"个房间的比赛规则");
						callback(null, pids);
					}
				}
			);
			conn.release();
			//setInterval(query, 5000);
		});
		//conn.end();
	},
	loadOptions: ['loadQuestions', function(callback,data) {
		var list = data.loadQuestions;
		for(var row in list) {
			var id = list[row].id;//房间ID
			var listId = list[row].listId;//题单id
		//	console.log("尝试为"+id+"加载题单:"+listId);
			common.makeQuestionForRoom(id,listId);
		//	conn.end();
		}
		//为天梯玩家配对的计划任务
		var schedule = require("node-schedule");
		var rule = new schedule.RecurrenceRule();
　　	var times = [];
	　　for(var i=1; i<60; i++) {
			if(i%2 == 0) times.push(i);
	　　}
　　	rule.second = times;
	　　var j = schedule.scheduleJob(rule, function() {
			var size = common.arraySize(searchingPlayers);
		  　if(size > 1) {
				for(var i in searchingPlayers) {
					var id = searchingPlayers[i].id;
					var p = searchingPlayers[i].point;//当前玩家分数
					var name = searchingPlayers[i].name;
					var head = searchingPlayers[i].head;
					if(typeof(ladders[id]) == "undefined") {
						searchingPlayers.splice(i, 1);
						continue;
					}
					searchingPlayers[i].count = searchingPlayers[i].count + 1;
					for(var j in searchingPlayers) {
						var tid = searchingPlayers[j].id;
						var tp = searchingPlayers[j].point;//对手玩家
						var tname = searchingPlayers[j].name;
						var thead = searchingPlayers[j].head;
						if(tid == id) continue;
						if(typeof(ladders[tid]) == "undefined") {
							searchingPlayers.splice(j, 1);
							continue;
						}
						var cha = 0;
						if(p > tp) cha = p - tp;
						else cha = tp - p;
						if(cha > (50*searchingPlayers[i].count)) continue;//每次匹配对手失败都会降低50分的匹配度
						else {
							//通知两位玩家
							//console.log('匹配成功了两个玩家,'+name+" 与 "+tname+" 开始对战");
							io.sockets.connected[ladders[id].socketId].emit('search',{room:id,target:tname,head:thead});
							io.sockets.connected[ladders[tid].socketId].emit('search',{room:id,target:name,head:head});
							if(j>i) {
								searchingPlayers.splice(j, 1);
								searchingPlayers.splice(i, 1);
							} else {
								searchingPlayers.splice(i, 1);
								searchingPlayers.splice(j, 1);
							}
							if(battles[id]) delete battles[id];
							battles[id] = {status:0,players:{},useTool:{},currentIndex:0,questions:[],answers:{},ready:{},sevenClassifies:[],gameClassifies:[],seconds:0,delay:0,ELO:'',winner:''};
							battles[id].players[id] = {head:head,name:name,point:0,cups:p,isOnline:true};
							battles[id].useTool[id] = {tool1:0,tool2:0,tool3:0};
							battles[id].players[tid] = {head:thead,name:tname,point:0,cups:tp,isOnline:true};
							battles[id].useTool[tid] = {tool1:0,tool2:0,tool3:0};
							common.writeLog(name+" 与 "+tname+" 开始对战");
							var t = require('silly-datetime');
							var time = t.format(new Date(), 'HH:mm');
							sockets.in('admin').emit('comment', {content:name+" 与 "+tname+" 开始对战",time:time});
						//	io.sockets.connected[ladders[id].socketId].emit('news',{type:1,msg:"正在生成题目"});
						//	io.sockets.connected[ladders[tid].socketId].emit('news',{type:1,msg:"正在生成题目"});
							//common.makeRandomClassifies(id);
							common.getSevenClassifies(id);//随机抓取7个大类
							break;
						}
					}
				}
			}
	　　});
		//处理每场天梯比赛是否开始的计划任务
		var rule2 = new schedule.RecurrenceRule();
　　	var seconds = [];
	　　for(var i=1; i<60; i++) {
			seconds.push(i);
	　　}
　　	rule2.second = seconds;
	　　var j2 = schedule.scheduleJob(rule2, function() {
			  var size = common.arraySize(battles);
			 // console.log("计划任务2开始运行:"+size);
		  　　if(size > 0) {
				for(var id in battles) {
					var battle = battles[id];
					if(battle.status == 0) {//判断备选类目是否加载成功
						if(battle.sevenClassifies.length >= 7) {
							for(var i in battle.players) {
								if(typeof(ladders[i]) != "undefined") //通知玩家开始指令	
									io.sockets.connected[ladders[i].socketId].emit('pushClassifies',battle.sevenClassifies);
							//	else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
							}
							battle.status = 1;
						}
					} else if(battle.status == 1) {//收集玩家的选择类目
					//	 console.log("天梯房间 "+id+"开始收集玩家的选择类目");
						 var size = battle.gameClassifies.length;
						 if(size >= 2) {
							for(var i in battle.players) {
								if(typeof(ladders[i]) != "undefined")
									io.sockets.connected[ladders[i].socketId].emit('news',{type:1,msg:"正在生成题目",pushData:[]});
							//	else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
							}
							common.fillQuestionForRoom(id);
							battle.status = 10;
							battle.seconds = 0;
							continue;
						 } else {
							battle.seconds++;
							if(battle.seconds >= 14) {//如果选择超时,则自动选择一个类目
								pushData = [];
								if(size == 0) {
									//随机选取2个类目
									var arr = common.getRandomArrayElements(battle.sevenClassifies, 2);
									for(var i in arr) {
										battle.gameClassifies.push(arr[i].id);
										pushData.push(arr[i].id);
									}
									//battle.gameClassifies.push(battle.sevenClassifies[0].id);
									//battle.gameClassifies.push(battle.sevenClassifies[1].id);
								} else {
									//随机选取1个类目
									var c = battle.gameClassifies[0];
									var sources = [];
									for(var i in battle.sevenClassifies) {
										var clazz = battle.sevenClassifies[i];
										if(clazz.id != c) {
											sources.push(clazz);
										}
									}
									var arr = common.getRandomArrayElements(sources, 1);
									battle.gameClassifies.push(arr[0].id);
									pushData.push(arr[0].id);
									/*
									for(var i in battle.sevenClassifies) {
										var clazz = battle.sevenClassifies[i];
										if(clazz.id != c) {
											battle.gameClassifies.push(clazz.id);
											break;
										}
									}*/
								}
								for(var i in battle.players) {
									if(typeof(ladders[i]) != "undefined") //通知玩家开始指令	
										io.sockets.connected[ladders[i].socketId].emit('news',{type:1,msg:"正在生成题目",pushData:pushData});
								//	else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
								}	
								common.fillQuestionForRoom(id);
								battle.status = 10;
								battle.seconds = 0;
								continue;
							}
						 }
					} else if(battle.status == 10) { //检查生成试题是否完成，完成则跳页
						if(battle.questions.length >= 10) {
							var classifyName = battle.questions[0].classify;
							var list1 = [];
							var list2 = [];
							var list = [];
							for(var i in battle.questions) {
								var q = battle.questions[i];
							//	console.log('Title:'+q.title);
								if(q.classify == classifyName) list1.push(q);
								else list2.push(q);
							}
							for(var i = 0;i<5;i++) {
								list.push(list1[i]);
								list.push(list2[i]);
							}
							battle.questions = list;//两个题类错开一道一道显示
							for(var i in battle.players) {
								if(typeof(ladders[i]) != "undefined") {//通知玩家开始指令
									io.sockets.connected[ladders[i].socketId].emit('news',{type:2,msg:id});//通知玩家跳页
								//	delete connectionList[ladders[i].socketId];//强制清除死链
								//	delete ladders[i];
								}
							//	else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
							}
							battle.status = 11;
							battle.seconds = 0;
						}
					} else if(battle.status == 11) { //收集玩家的准备指令,可以开始比赛
						 var size = common.arraySize(battle.ready);
					//	 console.log('判断ready:'+size);
						 if(size >= 2) {
							battle.status = 2;
							battle.seconds = 0;
							continue;
						 } else {
							battle.seconds++;
							if(battle.seconds == 120) {
					//			console.log("天梯房间 "+id+"因为玩家超时未准备而关闭");
								delete battles[id];
								continue;
							}
						 }
					} else if(battle.status == 2) { //授意玩家 Ready Go
						if(battle.seconds >= 2) {
							battle.status = 3;
							battle.seconds = 0;
							continue;
						} else if(battle.seconds == 0) {
					//		console.log('天梯房间'+id+'推送Ready Go');
							for(var i in battle.players) {
								if(typeof(ladders[i]) != "undefined")	
									io.sockets.connected[ladders[i].socketId].emit('news',{type:3,msg:id});//通知玩家Ready Go
				//				else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
							}
						}
						battle.seconds++;						
					} else if(battle.status == 3) { //处理比赛进程,题目推送和判断游戏是否结束	
						if(battle.seconds >= 12) {
							battle.seconds = 0;
							if(battle.currentIndex > 9) {
								battle.status = 4;
								common.balanceCups(battle);
								continue;
							}
							continue;
						} else if(battle.seconds == 0) { //推送题目
							battle.delay = 0;
							battle.answers = {};
							for(var i in battle.players) {
								var obj = battle.questions[battle.currentIndex];
								var cloneObj = {number:battle.currentIndex+1,title:obj.title,options:obj.options,author:obj.author,classify:obj.classify,type:obj.type,src:obj.src};
								if(typeof(ladders[i]) != "undefined")	
									io.sockets.connected[ladders[i].socketId].emit('pushQuestion',cloneObj);
						//		else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
							}
							battle.currentIndex++;
						} else if(common.arraySize(battle.answers) >= 2) { //当前题目已经都回答了,推送题目
							if(battle.delay >= 2) {
								if(battle.currentIndex > 9) {
									battle.status = 4;
									common.balanceCups(battle);
									continue;
								}
								battle.delay = 0;
								battle.seconds = 0;
								battle.answers = {};
								for(var i in battle.players) {
									var obj = battle.questions[battle.currentIndex];
									var cloneObj = {number:battle.currentIndex+1,title:obj.title,options:obj.options,author:obj.author,classify:obj.classify,type:obj.type,src:obj.src};
									if(typeof(ladders[i]) != "undefined")	
										io.sockets.connected[ladders[i].socketId].emit('pushQuestion',cloneObj);
							//		else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
								}
								battle.currentIndex++;
							} else battle.delay++;
						}
						battle.seconds++;
					} else if(battle.status == 4 && battle.ELO != '' && battle.winner != '') {
						for(var i in battle.players) {
							if(typeof(ladders[i]) != "undefined")
								io.sockets.connected[ladders[i].socketId].emit('gameover',{ELO:battle.ELO,winner:battle.winner});
						//	else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
						}
						battle.status = 5;
						battle.seconds = 0;
						battle.delay = 0;
						continue;
					} else if(battle.status == 5) {
						battle.delay = battle.delay + 1;
						if(++battle.delay >= 5) delete battles[id];
						continue;
					}
				}
			  }
	　　});
		//处理每日玩家已答题目的记录
		var rule3 = new schedule.RecurrenceRule();
　		rule3.minute = 0;
　　	rule3.hour = 0;
	　　var j3 = schedule.scheduleJob(rule3, function() {
			var t = require('silly-datetime');
			var date = t.format(new Date(), 'MM-DD HH:mm');
			console.log(date);
			for(var i in playerData) {
				delete playerData[i];
			}
			//每个月初所有玩家清空杯数
			if(t.format(new Date(), 'DD') == '01') {
				common.clearCpus();
			}
		});
		//处理小程序玩家断线重连的计划任务
		var schedule = require("node-schedule");
		var rule4 = new schedule.RecurrenceRule();
　　	var times2 = [];
	　　for(var i=1; i<60; i++) {
			if(i%5 == 0) times2.push(i);
	　　}
　　	rule4.second = times2;
	　　var j4 = schedule.scheduleJob(rule4, function() {
			for(var socketId in connectionList) {
				io.sockets.connected[socketId].emit('keepAlive',1);
			}
		});
		callback();
	}]
}, function(err, results) {
//	console.log('1.1: err: ', err); 
//	console.log('1.1: results: ', results);
});

io.on('connection', function (socket) {
	socket.on('add user', function (data) { //小程序测试
		socket.emit('login' , 'success');
	});
	socket.on('new message', function (data) { //小程序测试
		socket.broadcast.emit('new message' , data);
	});
	 // socket.emit('news',{ hello: 'Session ' + socket.id });
	var socketId = socket.id;
	console.log("新socket连入:"+socketId);
	async.auto({
		wxLogin: function (callback) {
			socket.on('wxLogin', function (data) { //小程序登录
				//var unid = common.getUnionID(data.code);
				//console.log("returnVal:"+unid);
				
				var https_request = {
					hostname:'api.weixin.qq.com',
					port: 443,
					method: 'GET',
					path:'/sns/jscode2session?appid='+APP_ID+'&secret='+APP_SECRET+'&js_code='+data.code+'&grant_type=authorization_code'
				}
				var req = https.request(https_request,function(res) {
					res.setEncoding('utf8');
					res.on('data',function(result) {
					//	console.log('UnionID:'+result);
						var info = eval('('+result+')');
						if(typeof(info.errmsg) != "undefined") {
							console.log('errmsg:'+info.errmsg);
							socket.emit('login' , 0);
							socket.disconnect();
							return;
						}
						callback(null, {openid:info.openid,'name':data.nickName,'head':data.head});
					});
				});
				req.on('error', (e) => {
				  console.error(e);
				});
				req.end();
			});
		},
		readRedis: ['wxLogin', function(callback,data) {
			var pool = common.getPool();
			pool.getConnection(function (err, conn) {
				if (err) {
					console.log("POOL ==> " + err);
					return;
				}
				conn.query('SELECT * FROM answer_user WHERE openid=? AND roleID=? and status=?', [data.wxLogin.openid,2,1],
				function(error, results) {
					if(error) {
				//		console.log("ClientReady Error: " + error.message);
					//	conn.end();
						socket.emit('login' , 0);
						socket.disconnect();
						return;
					}
					var time = common.getTimeStamp();
					if(results.length > 0) {
						var row = results[0];
						connectionList[socketId] = {id:row.id,authentication:true,role:false,name:row.name,room:false,point:row.point,roomIndex:-1,ready:false,head:'head.jpg'};
					//	console.log("登录游戏成功");
						conn.query('UPDATE answer_user SET account=?,wx_head=?,last_login=? WHERE id=?', [data.wxLogin.name,data.wxLogin.head,time,row.id],
							function(error, results2) {
								if(error) {
									return;
								}
							}
						);
						socket.emit('login' , {id:row.id,point:row.point,continuous:row.continuous,tool1:row.tool1,tool2:row.tool2,tool3:row.tool3,socketId:socketId});
						
						socket.join('ladder');
						console.log("加入天梯大厅成功:"+row.id+":"+data.wxLogin.name);
						ladders[row.id] = {socketId:socketId,name:data.wxLogin.name};
						callback(null, row);
					} else {	
						console.log("首次登录游戏");
						conn.query('INSERT INTO answer_user(account,openid,roleID,head,wx_head,point,tool1,tool2,tool3,continuous,last_login,status) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)', [data.wxLogin.name,data.wxLogin.openid,'2','head.jpg',data.wxLogin.head,0,1,1,1,0,time,1],
							function(error, results3) {
								if(error) {
									return;
								}
							//	console.log("新增用户:"+results.insertId);
								connectionList[socketId] = {id:results3.insertId,authentication:true,role:false,name:data.wxLogin.name,room:false,point:0,roomIndex:-1,ready:false,head:'head.jpg'};
								socket.emit('login' , {id:results3.insertId,point:0,continuous:0,tool1:1,tool2:1,tool3:1,socketId:socketId});
								socket.join('ladder');
								ladders[results3.insertId] = {socketId:socketId,name:data.wxLogin.name};
								callback();
							}
						);
						
					//	socket.disconnect();
					}
				});
				conn.release();
			});
			/*
			if(!connectionList[socketId].authentication) {
				socket.emit('login' , 0);
				socket.disconnect();
				return;
			}*/
		//	socket.emit('login' , 1);
		//	console.log("验证通过");
		//	socket.join('ladder');//加入天梯房间
		//	ladders[data.wxLogin.id] = {socketId:socketId,name:data.wxLogin.name};
		//	callback();
		}],
		nickname: ['readRedis', function(callback) {
			callback(null,"OK");
		}]
	}, function(err, results) {
	//	console.log('1.1: err: ', err); 
	//	console.log('1.1: results: ', results);
	});
	  async.auto({
		login: function (callback) {
			socket.on('login', function (data) { //天梯模式登录
			//	console.log("开始验证:"+data.name);
				connectionList[socketId] = {id:data.id,authentication:false,role:false,name:data.name,room:false,point:data.point,roomIndex:-1,ready:false,head:'head.jpg'};
				var pool = common.getPool();
				pool.getConnection(function (err, conn) {
					if (err) {
						console.log("POOL ==> " + err);
						return;
					}
					conn.query('SELECT * FROM answer_user WHERE id=? AND account=? AND pwd=?', [data.id,data.name,data.pwd],
					function(error, results) {
						if(error) {
					//		console.log("ClientReady Error: " + error.message);
						//	conn.end();
							socket.emit('login' , 0);
							socket.disconnect();
							return;
						}
						if(results.length > 0) {
							connectionList[socketId].authentication = true;
							callback(null, data);
						} else {
					//		console.log("验证不通过");
							socket.emit('login' , 0);
							socket.disconnect();
							return;
						}
					});
					conn.release();
				});
			});
		},
		readRedis: ['login', function(callback,data) {
			if(!connectionList[socketId].authentication) {
			//	console.log("验证不通过");
				socket.emit('login' , 0);
				socket.disconnect();
				return;
			}
			socket.emit('login' , 1);
		//	console.log("验证通过");
			socket.join('ladder');//加入天梯房间
			ladders[data.login.id] = {socketId:socketId,name:data.login.name};
			callback();
		}],
		nickname: ['readRedis', function(callback) {
			callback(null,"OK");
		}]
	}, function(err, results) {
	//	console.log('1.1: err: ', err); 
	//	console.log('1.1: results: ', results);
	});
	  async.auto({
		authentication: function (callback) {
			socket.on('authentication', function (data) {//验证抢答与半即时答题登录
			//	console.log("开始验证:"+data.role);
				connectionList[socketId] = {authentication:false,role:false,name:false,room:false,point:0,ready:false,head:data.head};
				if(data.role == 'admin') {
					var pool = common.getPool();
					pool.getConnection(function (err, conn) {
						if (err) {
							console.log("POOL ==> " + err);
							return;
						}
						conn.query('SELECT * FROM answer_user WHERE account=? AND pwd=?',[data.name,data.pwd],
						 function(error, results) {
							if(error) {
						//		console.log("ClientReady Error: " + error.message);
							//	conn.end();
								socket.emit('result' , 0);
								socket.disconnect();
								return;
							}
							if(results.length > 0) {
								connectionList[socketId].role = 'admin';
								connectionList[socketId].authentication = true;	
								callback(null, data);
								/*
								var firstResult = results[0]; 
								console.log('First Name: ' + firstResult['firstname']); 
								console.log('Last Name: ' + firstResult['lastname']); 
								console.log('Message: ' + firstResult['message']); */
							} else {
					//			console.log("验证不通过");
								socket.emit('result' , 0);
								socket.disconnect();
								return;
							}
						 }
						);
						conn.release();
					});
				} else if(data.role == 'player') {
					//判断参赛人数上限与重名
					var id = data.room;
					if (!rooms[id]) {
				//		console.log("初次验证,创建房间");
						rooms[id] = [];	
						connectionList[socketId].role = 'player';
						connectionList[socketId].authentication = true;
						callback(null, data);
					} else {
						//console.log("玩家身份验证！！");
						var size = rooms[id].length;
						if(!games[id]) {
						//	 console.log("验证不通过1");
							 socket.emit('result' , 0);
							 socket.disconnect();
							 return;
						}
						if(games[id].number <= size) {
						//	console.log("房间人数已满，无法进入");
							socket.emit('result' , 2);
							socket.disconnect();
							return;
						}
						//var list = rooms[id];
						//console.log("当前房间列表:"+list);
						var bo = true;
						/*
						for (var i in list) { //判断是否有重名
							var row = list[i];
							if(typeof(connectionList[row]) == "undefined") continue;
							if(connectionList[row].name == data.name) {
								bo = false;
								break;
							}
						}*/
						if(bo) {
							connectionList[socketId].role = 'player';
							connectionList[socketId].authentication = true;
							//console.log("基本已通过验证!!");
							callback(null, data);	
						} else {
							//console.log("验证不通过:重名");
							socket.emit('result' , 3);
							socket.disconnect();
							return;
						}
					}
				} else {
			//		console.log("验证不通过");
					socket.emit('result' , 0);
					socket.disconnect();
					return;
				}
				//if(data.username == "tom" || data.username == 'jerry') connectionList[socketId].authentication = true;
			});
		},
		readRedis: ['authentication', function(callback,data) {
			if(!connectionList[socketId].authentication) {
				//console.log("验证不通过2");
				socket.emit('result' , 0);
				socket.disconnect();
				return;
			}
			var id = data.authentication.room;
			var name = data.authentication.name;
			var role = connectionList[socketId].role == 'admin'?"裁判":"参赛者";
			//if(id != '') console.log("游戏状态:"+games[id].status);
			if(role == '参赛者' && games[id].status == 2) {//选手重新进比赛时拉取自己的成绩和头像
				if(typeof(games[id].points[name]) == "undefined") {
					//console.log("验证不通过:游戏已经开始");
					socket.emit('result' , 4);
					socket.disconnect();
					return;
				}
				connectionList[socketId].point = games[id].points[name];
				connectionList[socketId].head = games[id].heads[name];
			}
			socket.emit('result' , 1);
			//console.log("验证通过");
			connectionList[socketId].name = name;
			connectionList[socketId].room = id;
			if(id != '') {//加入房间  可能管理员进入大厅页面
				if(role == '参赛者') {
					socket.join(id);
				} else {
					socket.join("admin"+id);
				}
			//	console.log(role+" "+name+" 加入了房间 "+id);
			} else {
				socket.join('admin');
			//	console.log(role+" "+name+" 进入了游戏");	
			}
			if(role == '参赛者') {
				rooms[id].push(socketId);
				connectionList[socketId].roomIndex = common.admeasureRoomIndex(rooms[id],connectionList,name);
			//	console.log("参赛者"+name+"在房间"+id+"中被分配到了:"+connectionList[socketId].roomIndex);
				socket.broadcast.in(id).emit('join' ,{socketId:socketId,name:name,point:connectionList[socketId].point,head:connectionList[socketId].head});//通知本房间的其他用户自己进入了房间
				io.sockets.in('admin'+id).emit('join' ,{socketId:socketId,name:name,point:connectionList[socketId].point,head:connectionList[socketId].head});//通知本房间的其他用户自己进入了房间
			}
			callback();
			/*
			redisClient.get("PHPREDIS_SESSION:"+data.authentication,function(error, res) {
				var val = '0';
				if(error) {
					console.log("错误:"+error);
					socket.disconnect();
				} else {
					val = '1';
					if(res != null) connectionList[socketId].authentication = true;
					else socket.disconnect();
				}
				socket.emit('result' , val);
				callback();
			});*/
		}],
		nickname: ['readRedis', function(callback) {
			callback(null,"OK");
		}]
	}, function(err, results) {
	//	console.log('1.1: err: ', err); 
	//	console.log('1.1: results: ', results);
	});
	//尝试加入房间
    socket.on('join', function (data) {
		connectionList[socketId] = {authentication:false,role:false,uid:false,name:false,room:false,point:0,ready:false,head:data.head};
		var id = data.room;
		var name = data.name;
		var uid = data.uid;
		if (!rooms[id]) {
			rooms[id] = [];	
			connectionList[socketId].role = 'player';
			connectionList[socketId].authentication = true;
		} else {
			var size = rooms[id].length;
			if(!games[id]) {
				 socket.emit('result' , 0);
				 return;
			}
			if(games[id].number <= size) {
				socket.emit('result' , 2);
				return;
			}
			var bo = true;
			for (var i in rooms[id]) {
				if(rooms[id][i] == socketId) {
					bo = false;
					break;
				}
			}
			if(!bo) {
				 socket.emit('result' , 3); //已经进入了游戏只是网络延迟
				 return;
			}
			connectionList[socketId].role = 'player';
			connectionList[socketId].authentication = true;
		}
		var role = connectionList[socketId].role == 'admin'?"裁判":"参赛者";
		//if(id != '') console.log("游戏状态:"+games[id].status);
		if(role == '参赛者' && games[id].status == 2) {//选手重新进比赛时拉取自己的成绩和头像
			if(typeof(games[id].points[name]) == "undefined") {
				console.log("验证不通过:游戏已经开始");
				socket.emit('result' , 4);
				socket.disconnect();
				return;
			}
			connectionList[socketId].point = games[id].points[name];
			connectionList[socketId].head = games[id].heads[name];
		}
		socket.emit('result' , 1);
		connectionList[socketId].uid = uid;
		connectionList[socketId].name = name;
		connectionList[socketId].room = id;
		if(id != '') socket.join(id);
		if(role == '参赛者') {
			rooms[id].push(socketId);
			connectionList[socketId].roomIndex = common.admeasureRoomIndex(rooms[id],connectionList,name);
			socket.broadcast.in(id).emit('join' ,{roomIndex:connectionList[socketId].roomIndex,uid:uid,name:name,point:connectionList[socketId].point,head:connectionList[socketId].head});//通知本房间的其他用户自己进入了房间
			io.sockets.in('admin'+id).emit('join' ,{roomIndex:connectionList[socketId].roomIndex,uid:uid,name:name,point:connectionList[socketId].point,head:connectionList[socketId].head});//通知本房间的其他用户自己进入了房间
		}
    });
	//获取客户端发来的普通消息
    socket.on('message', function (msg) {
    //    console.log('Message Received: ', msg);
		var nickname = connectionList[socketId].name;
		socket.broadcast.emit('message', 'From ' + nickname + ': ' + msg);
    });
	//监听用户离开房间
    socket.on('leftRoom', function (data) {
	    socket.broadcast.in(data.room).emit('leave' ,{name:data.name,uid:data.uid});//通知本房间的其他用户自己离开了房间
		io.sockets.in('admin'+data.room).emit('leave',{name:data.name,uid:data.uid});
		if(typeof(rooms[data.room]) != "undefined") {
			var index = rooms[data.room].indexOf(data.socketId);
			if (index !== -1) {
				rooms[data.room].splice(index, 1);
			}
		}
    });
	//用户签到
	socket.on('sign',function (data) {
		console.log(data.id+"进行签到操作");
		var pool = common.getPool();
		pool.getConnection(function (err, conn) {
			if (err) {
				console.log("POOL ==> " + err);
				return;
			}
			var today = common.getToday();
			var yesterday = common.getYesterday();
			conn.query('select * from answer_sign WHERE uid=? AND signDate=?', [data.id,today],function(error, results) {//查看今日是否已经登录
				if(error) {
					console.log(error);
					return;
				}
				var time = common.getTimeStamp();
				if(results.length > 0) {
					socket.emit('sign', '0');
					return;
				} else {
					var stringTime = today+" 23:59:59";  
					var endTime = Date.parse(new Date(stringTime));  
					endTime = endTime / 1000;
					stringTime = yesterday + " 00:00:00";  
					var startTime = Date.parse(new Date(stringTime));  
					startTime = startTime / 1000;
					conn.query("SELECT * FROM answer_sign WHERE timestamp<? AND uid=?", [startTime,data.id],function(error, results4) { //查看昨天之前是否登录过
						if(error) {
							console.log(error);
							return;
						}
						var id = 0;
						var sql = 'INSERT INTO answer_sign(uid,signDate,timestamp) VALUES(?,?,?)';
						var args = [data.id,today,time];
						if(results4.length > 0) {
							sql = 'UPDATE answer_sign SET signDate=?,timestamp=? WHERE id=?';
							args = [today,time,results4[0].id];
						}
						conn.query(sql, args, function(error, results2) { //记录玩家签到
							if(error) {
								console.log(error);
								return;
							}
							var returnVal = '1';
							conn.query("select * from answer_sign WHERE signDate=? AND uid=?", [yesterday,data.id],function(error, results3) {//判断用户昨天是否登录过
								if(error) {
									console.log(error);
									return;
								}
								if(results3.length > 0) {
									data.continuous = data.continuous + 1;
								} else {
									data.continuous = 1;
								}
								var count = 1;
								if(data.continuous > 10) count = 2;
								data.tool1 = data.tool1 + count;
								if(data.continuous % 5 == 0) {
									data.tool2 = data.tool2 + count;
									returnVal += ',2';
								}
								if(data.continuous % 3 == 0) {
									data.tool3 = data.tool3 + count;
									returnVal += ',3';
								}
								conn.query("UPDATE answer_user SET tool1=?,tool2=?,tool3=?,continuous=? WHERE id=?", [data.tool1,data.tool2,data.tool3,data.continuous,data.id],function(error, results5) {
									if(error) {
										console.log(error);
										return;
									}
									socket.emit('sign', {continuous:data.continuous,tool1:data.tool1,tool2:data.tool2,tool3:data.tool3});
								});
							});		
						});
					});
				//	socket.disconnect();
				}
			});
			conn.release();
		});
	});
	
	socket.on('upload', function (data) { //玩家上传题目
		var classifyID = data.classifyID;
		var title = data.title;
		var uid = data.uid;
		var options = [data.a,data.b,data.c,data.d];
		if(uid == '') {
			socket.emit('uploadResult',-1);
			return;
		}
		var pool = common.getPool();
		pool.getConnection(function (err, conn) {
			if (err) {
				console.log("POOL ==> " + err);
				return;
			}
			var time = common.getTimeStamp();
			conn.query("INSERT INTO answer_question(classifyID,authorID,title,result,addTime,status) VALUES(?,?,?,?,?,?)", [classifyID,uid,title,1,time,2],function(error, result) {
				if(error) {
					console.log(error);
					return;
				}
				var qid = result.insertId;
				if(qid > 0) {
					for(var i = 0;i < options.length;i++) {
						conn.query("INSERT INTO answer_option(`questionID`,`index`,`content`) VALUES(?,?,?)", [qid,i+1,options[i]],function(error, result2) {
							if(error) {
								console.log(error);
								return;
							}
						});	
					}
					socket.emit('uploadResult',1);
				}
			});
			conn.release();
		});
		
    });
	socket.on('top10', function (data) { //查看SOLO天梯top10
		var pool = common.getPool();
		pool.getConnection(function (err, conn) {
			if (err) {
				console.log("POOL ==> " + err);
				return;
			}
			var time = common.getTimeStamp();
			conn.query("select account,point,head,wx_head from answer_user WHERE roleID=? AND status=? and id>179 order by point DESC,last_login DESC,id LIMIT ?", [2,1,10],function(error, results) {
				if(error) {
					console.log(error);
					return;
				}
				var data = {};
				if(results.length > 0) {
					var index = 1;
					var point = 0;
					for(var i = 0;i < results.length;i++) {
						results[i].index = 1;
						if(point > results[i].point) index++;
						if(index >= 10) results[i].index = index;
						else  results[i].index = '0' + index;
						point = results[i].point;
						data[i] = results[i];
					}
					socket.emit('top10',data);
				} else socket.emit('top10','{}');
			});
			conn.release();
		});
    });
	
	socket.on('ready', function (data) { //处理参赛者的准备指令
		var id = data.room;
		var name = data.name;
		var uid = data.uid;
		var ready = data.ready;
		if(typeof(rooms[id]) != "undefined") {
			  var bo = false;
			  var list = rooms[id];
			  var players = [];
			  for (var i in list) {
				  var socketId = list[i];
				  if(typeof(connectionList[socketId]) == "undefined") {
					  continue;
				  }
				  if(connectionList[socketId].name == name) {
					connectionList[socketId].ready = ready;
					bo = true;
					break;
				  }
			  }
			  if(bo) {
				io.sockets.in(id).emit('ready', {name:name,ready:ready,uid:uid});
				io.sockets.in('admin'+id).emit('ready', {name:name,ready:ready,uid:uid});
			  }
			  else socket.emit('result' , {name:name,ready:'error'});
		} else socket.emit('result' , {name:name,ready:'error'});
    });
	
	socket.on('grab', function (data) { //处理参赛者的抢答指令
		var room = data.room;
		var name = data.name;
	//	console.log("房间 "+room+" 的 "+name+" 尝试抢答");
		if(games[room].open == 1 && games[room].status == 2) {
			var blackList = games[room].blackList;
			var bo = true;
			for(var i in blackList) {
				var player = blackList[i];
				if(player == name) {
					 bo = false;
					 break;
				}
			}
			if(bo) {
				games[room].open = 0;
				games[room].player = name;
				io.sockets.in(room).emit('grab', name);
				io.sockets.in('admin'+room).emit('grab', name);
			}
		}
    });
	socket.on('editRoom', function (data) { //处理裁判的指令:修改房间规则
		var room = data.room;
		var number = data.number;
	//	console.log('修改房间'+data.room+' 人数:'+number);
		if(games[room]) {
			games[room].blackList = [];
			games[room].open = 1;
			games[room].player = '';
			games[room].begin = false;
			games[room].number = number;
			io.sockets.in('admin'+room).emit('editRoom', 1);
		}
    });
	socket.on('addRoom', function (data) { //处理裁判的指令:添加一个房间
		var room = data.room;
		var number = data.number;
		var type = data.type;
		var listID = data.listID;
		//games[room] = {begin:false,status:1,number:number,open:1,player:'',heads:[],points:[],blackList:[]};
		games[room] = {begin:false,type:type,mode:1,listID:listID,status:1,number:number,open:1,player:'',points:[],blackList:[],heads:[],questions:[],currentIndex:0,allow:0,answers:{},queries:[]};
		if(listID > 0) {
		//	console.log("尝试为"+id+"加载题单:"+listId);
			common.makeQuestionForRoom(room,listID);
		}
	//	console.log('添加了房间'+room+' 人数:'+number);
    });
	socket.on('shield', function (data) { //处理裁判的指令:屏蔽指定参赛者
		var room = data.room;
		var name = data.name;
		if(games[room].open == 0 && games[room].status == 2) {
			games[room].open = 1;
			games[room].player = '';
			games[room].blackList.push(name);
			io.sockets.in(room).emit('shield', name);
			io.sockets.in('admin'+room).emit('shield', name);
		}
    });
	socket.on('load', function (room) { //裁判拉取当前比赛是否有抢答者
		if(typeof(games[room]) != "undefined") {
			var player = games[room].player;
			var open   = games[room].open;
			socket.emit('load', {player:player,open:open});
		}
    });
	socket.on('point', function (data) { //处理裁判的指令:为参赛者加减分
		var room = data.room;
		var name   = data.name;
		var point  = data.point;
		var result = 0;
		if(typeof(rooms[room]) != "undefined") {
			  var bo = false;
			  var list = rooms[room];
			  for (var i in list) {
				  var socketId = list[i];
				  if(typeof(connectionList[socketId]) == "undefined") {
					  continue;
				  }
				  if(connectionList[socketId].name == name) {
						result = parseInt(connectionList[socketId].point) + parseInt(point);
						if(result <= 0) result = 0;
						connectionList[socketId].point = result;
						break;	
				  }
			  }
			  games[room].points[name] = result;
			  io.sockets.in(room).emit('point',{name:name,point:result});
			  io.sockets.in('admin'+room).emit('point',{name:name,point:result,tag:point});
		}
    });
	socket.on('clear', function (room) {
		if(typeof(games[room]) == "undefined") {
			io.sockets.in('admin'+room).emit('next',-1);
			return;
		}
		games[room].open = 1;
		io.sockets.in('admin'+room).emit('clear',1);
	});
	socket.on('next', function (data) { //处理裁判的指令:下一题(抢答模式)
		var room = data.room;
		if(typeof(games[room]) == "undefined") {
			io.sockets.in('admin'+room).emit('next',-1);
			return;
		}
		if(!games[room].begin) return;
		if(typeof(games[room].questions) != "undefined" && games[room].status == 2) {
			var index = games[room].currentIndex;
			//判断所有参赛者是否已经都提交了答案
			if(games[room].questions.length <= index+1) {
				io.sockets.in('admin'+room).emit('next','gameover');
			} else {
				games[room].currentIndex++;
				var obj = games[room].questions[games[room].currentIndex];
				var cloneObj = {number:games[room].currentIndex+1,title:obj.title,options:obj.options,author:obj.author,classify:obj.classify,type:obj.type,src:obj.src};
				//io.sockets.in(room).emit('next',cloneObj);
				io.sockets.in('admin'+room).emit('next', cloneObj);

				games[room].blackList = [];
				games[room].open = 1;
				games[room].player = '';
				socket.broadcast.in(room).emit('next', 1);
			}
		}
    });
	socket.on('pullNextQuestion', function (room) { //处理裁判的指令:下一题(答题模式)
		var result = 0;
		if(typeof(games[room].questions) != "undefined") {
			var index = games[room].currentIndex;
			//判断所有参赛者是否已经都提交了答案
			if(typeof(games[room]) != "undefined") {
				  var list = games[room].answers;
				  var size = common.arraySize(list);
			//	  console.log(rooms[room].length+":"+size);
				  if(rooms[room].length == size) {
					  if(games[room].questions.length <= index+1) {
						   io.sockets.in('admin'+room).emit('pullNextQuestion','gameover');
					  } else {
							games[room].answers = {};
							games[room].allow = 0;
						    games[room].currentIndex++;
							var obj = games[room].questions[games[room].currentIndex];
							var cloneObj = {number:games[room].currentIndex+1,title:obj.title,options:obj.options,author:obj.author,classify:obj.classify,type:obj.type,src:obj.src};
							io.sockets.in(room).emit('pullNextQuestion',cloneObj);
							io.sockets.in('admin'+room).emit('pullNextQuestion',cloneObj);
					  }
				  } else {
					  io.sockets.in('admin'+room).emit('pullNextQuestion',0);
				  }
			} else {
					io.sockets.in('admin'+room).emit('pullNextQuestion',-1);
			}
		}
    });
	socket.on('getCurrentPushQuestion', function (id,uid) { //处理天梯玩家请求:拉取当前题目
		if(typeof(battles[id]) != "undefined") {
			var battle = battles[id];
			if(battle.status != 3) return;
			if(battle.currentIndex > 9) battle.currentIndex = 10;
			var obj = battle.questions[battle.currentIndex-1];
			var answer = 0;
			var result = 0;
			if(typeof(battle.answers[uid]) != "undefined") {
				answer = battle.answers[uid];
				result = battle.questions[battle.currentIndex-1].result == answer;
			}
			var cloneObj = {number:battle.currentIndex,title:obj.title,options:obj.options,author:obj.author,classify:obj.classify,type:obj.type,src:obj.src,answer:answer,result:result,seconds:battle.seconds,point:battle.players[uid].point};
			socket.emit('getCurrentPushQuestion',cloneObj);
		}
    });
	socket.on('pullCurrentQuestion', function (room) { //处理裁判的指令:拉取题目
		var result = 0;
		if(typeof(games[room].questions) != "undefined") {
			var index = games[room].currentIndex;
			if(!games[room].begin) return;
			if(typeof(games[room].questions[index]) != "undefined") {
				var obj = games[room].questions[index];
				var cloneObj = {number:index+1,title:obj.title,options:obj.options,author:obj.author,classify:obj.classify,type:obj.type,src:obj.src};
				socket.emit('pullCurrentQuestion',cloneObj);
			} else {
				socket.emit('pullCurrentQuestion',0);
			}
		} else {
			socket.emit('pullCurrentQuestion',0);
		}
    });
	
	socket.on('fetchPointAndHead', function (data) { //参赛者重新进入比赛时拉取自己的分数和头像
		var room = data.room;
		var name   = data.name;
		var result = 0;
		socket.emit('fetchPointAndHead',{point:games[room].points[name],head:games[room].heads[name]});
    });
	
	socket.on('expel',function (data) { //处理裁判的指令:踢出指定参赛者
		var name = data.name;
		var room = data.room;
		var uid = data.uid;
		if(typeof(rooms[room]) != "undefined") {
			  var bo = false;
			  var list = rooms[room];
			  for (var i in list) {
				  var socketId = list[i];
				  if(typeof(connectionList[socketId]) == "undefined") {
					  continue;
				  }
				  if(connectionList[socketId].uid == uid) {
				//	  console.log(name+" 被裁判从房间"+room+"中踢出");
					  io.sockets.in(room).emit('expel',{name:name,uid:uid});
					  io.sockets.in('admin'+room).emit('expel',{name:name,uid:uid});
					  rooms[room].splice(i, 1);
					  break;	
				  }
			  }
		}
	});
	socket.on('startGame',function (room) { //处理裁判的指令:开始比赛
		if (!games[room]) {
			socket.emit('startGame', '0');
			return;
		}
		games[room].status = 2;
		games[room].open = 1;
		games[room].player = '';
		games[room].begin = false;
		games[room].blackList=[];
		if(typeof(rooms[room]) != "undefined") {
			  var list = rooms[room];
			  for (var i in list) {
				  var socketId = list[i];
				  if(typeof(connectionList[socketId]) == "undefined") {
					  continue;
				  }
				  if(connectionList[socketId].role != 'admin') {
						games[room].points[connectionList[socketId].name] = 0;
						games[room].heads[connectionList[socketId].name] = connectionList[socketId].head;
				  }
			  }
			  //判断是否是答题模式
			  if(games[room].type == 2) {
				  games[room].currentIndex = 0;
			  }
			  io.sockets.in(room).emit('startGame', '1');
			  io.sockets.in('admin'+room).emit('startGame', '1');
			  //强制清除所有连接防止死链接产生
			  /*
			  for (var i in list) {
				  var socketId = list[i];
				  if(typeof(connectionList[socketId]) == "undefined") {
					  continue;
				  }
				  delete connectionList[socketId];
			  }
			  rooms[room] = [];*/
		}
	});
	socket.on('gameover',function (room) { //处理裁判的指令:结束比赛
		if (!rooms[room]) {
			socket.emit('gameover', '0');
			return;
		}
		games[room].status = 3;
		games[room].begin = false;
		games[room].open = 1;
		games[room].player = '';
		games[room].blackList=[];
		games[room].answers = {};
		games[room].queries = [];
		games[room].points = [];
		games[room].heads = [];
		games[room].currentIndex = 0;
		games[room].allow = 0;
		io.sockets.in(room).emit('gameover', '1');
		io.sockets.in('admin'+room).emit('gameover', '1');
	});
	socket.on('resetGame',function (room) { //处理裁判的指令:重新初始化比赛
		if (!rooms[room]) {
			socket.emit('resetGame', '0');
			return;
		}
		games[room].status = 1;
		games[room].begin = false;
		games[room].open = 1;
		games[room].player = '';
		games[room].blackList=[];
		games[room].answers = {};
		games[room].queries = [];
		games[room].points = [];
		games[room].heads = [];
		games[room].currentIndex = 0;
		games[room].allow = 0;
		io.sockets.in('admin'+room).emit('resetGame', '1');
	});
	socket.on('deleteRoom',function (room) { //处理裁判的指令:删除房间
		if (!games[room]) {
			socket.emit('deleteRoom', '0');
			return;
		}
		delete games[room];
		socket.emit('deleteRoom', '1');
	});
	socket.on('allowAnswer',function (room) { //处理裁判的指令:开始答当前题目
		if (!games[room]) {
			socket.emit('allowAnswer', '0');
			return;
		}
		games[room].allow = 1;
		games[room].queries = [];
		io.sockets.in(room).emit('allowAnswer', games[room].allow);
		io.sockets.in('admin'+room).emit('allowAnswer', games[room].allow);
	});
	socket.on('comment',function (data) { //接收天梯玩家的留言
		var content = data.content;
		var name = data.name;
		common.writeLog(name+" 说: "+content);
		var t = require('silly-datetime');
		var time = t.format(new Date(), 'HH:mm');
		io.sockets.in('ladder').emit('comment', {content:name+" 说: "+content,time:time});
		io.sockets.in('admin').emit('comment', {content:name+" 说: "+content,time:time});
	});
	socket.on('writeLog',function (data,bo) { //记日志
		common.writeLog(data);
		if(bo) {
			var t = require('silly-datetime');
			var time = t.format(new Date(), 'HH:mm');
			io.sockets.in('ladder').emit('comment', {content:data,time:time});
			io.sockets.in('admin').emit('comment', {content:data,time:time});
		}
	});
	
	socket.on('loadAnswer',function (data) { //处理比赛者的指令:加载对当前题目的状态
		var room = data.room;
		var name = data.name;
		if (!games[room]) {
			socket.emit('loadAnswer', 0);
			return;
		}
		var result = (games[room].answers[name] == games[room].questions[games[room].currentIndex].result)?1:0;
		socket.emit('loadAnswer', {name:name,answer:games[room].answers[name],result:result,allow:games[room].allow});
	});
	socket.on('query', function (data) { //处理比赛者的指令:提出质疑
		var room = data.room;
		var name = data.name;
		if(typeof(games[room]) != "undefined" && games[room].allow == 0) {
			games[room].queries.push(name);
			io.sockets.in(room).emit('query', name);
			io.sockets.in('admin'+room).emit('query', name);
		}
    });
	socket.on('search', function (data) { //匹配对手
		var id = data.id;
		var point = data.point;
		var name = data.name;
		var head = data.head;
		//console.log(id+" : "+name+"正在天梯匹配对手");
		common.writeLog(name+" 正在天梯匹配对手");
		searchingPlayers.push({id:id,point:point,name:data.name,head:head,count:0,socketId:socket.id});
		socket.broadcast.in('ladder').emit('news', {type:0,msg:name});//通知所有玩家
		var t = require('silly-datetime');
		var time = t.format(new Date(), 'HH:mm');
		io.sockets.in('ladder').emit('comment', {content:name+" 正在天梯匹配对手",time:time});
		io.sockets.in('admin').emit('comment', {content:name+" 正在天梯匹配对手",time:time});
		//searchingPlayers
		//ladders
		//io.sockets.connected[socketid]
    });
	socket.on('cancelSearch', function (id) { //取消匹配对手
		if(searchingPlayers.length > 0) {
			for(var i in searchingPlayers) {
				if(searchingPlayers[i].id == id) {
					searchingPlayers.splice(i, 1);
					break;
				}
			}
		}		
    });
	socket.on('ladders_ready', function (id,uid) { //天梯比赛通知房间玩家已准备
		if(battles[id]) {
			var battle = battles[id];
			battle.ready[uid] = '1';
		}
    });
	socket.on('ladders_quit', function (data) { //天梯比赛玩家比赛结束正常退出比赛
		var id = data.id;
		var uid = data.uid;
		if(battles[id]) {
			var battle = battles[id];
			battle.players[uid].isOnline = false;
		}
    });
	socket.on('exit_game', function (data) { //天梯比赛玩家强行退出比赛
		var id = data.id;
		var uid = data.uid;
		if(battles[id]) {
			var battle = battles[id];
			battle.players[uid].point = 0;
		//	console.log("天梯房间"+id+",玩家"+uid+"退出了游戏");
			battle.players[uid].isOnline = false;
			for(var pid in battle.players) {
				if(uid != pid) {
					if(typeof(ladders[pid]) != "undefined") {
						io.sockets.connected[ladders[pid].socketId].emit('exit_game',1);
					}// else console.log("天梯房间"+id+",玩家"+pid+"已经断线");
					break; 
				}
			}
			battle.status = 4;
			common.balanceCups(battle);
		}
    });
	socket.on('loadOpponent', function (id,uid) { //获取天梯对手的信息
		if(battles[id]) {
			var battle = battles[id];
			for(var id in battle.players) {
				if(uid != id) {
					socket.emit('loadOpponent', battle.players[id],battle.currentIndex);
					break; 
				}
			}
		} else socket.emit('loadOpponent', 0);
    });
	socket.on('emoticon', function (data) {//发表情
		var id = data.id;
		var uid = data.uid;
		var index = data.index;
		if(battles[id]) {
			var battle = battles[id];
			if(common.arraySize(battle.players) < 2) return;
			for(var i in battle.players) {
				if(uid == i) continue;
				if(!battle.players[i].isOnline) break;
				if(typeof(ladders[i]) != "undefined")	
					io.sockets.connected[ladders[i].socketId].emit('emoticon',index);
			}
		}
    });
	socket.on('loadUseTool', function (id,uid) { //加本局载使用道具数量
		if(battles[id]) {
			var battle = battles[id];
			socket.emit('loadUseTool', battle.useTool[uid]);
		}
    });
	socket.on('useTool', function (data) { //使用道具
		var id = data.id;
		var uid = data.uid;
		var index = data.index;
		if(battles[id]) {
			var battle = battles[id];
			if(common.arraySize(battle.players) < 2) return;
			if(index == 3) {
				for(var i in battle.players) {
					if(uid != i) continue;
					if(!battle.players[i].isOnline) break;
					var q = battle.questions[battle.currentIndex-1];
					var result = parseInt(q.result);
					var s = '2,4';
					if(result == 2 || result == 4) s = '1,3';
					if(typeof(ladders[i]) != "undefined") {
						io.sockets.connected[ladders[i].socketId].emit('useTool',s);
						battle.useTool[uid].tool3 = parseInt(battle.useTool[uid].tool3) + 1;
					}
						
				}
			} else {
				for(var i in battle.players) {
					if(uid == i) continue;
					if(!battle.players[i].isOnline) break;
					if(typeof(ladders[i]) != "undefined") {
						io.sockets.connected[ladders[i].socketId].emit('useTool',index);
						if(index == 1) battle.useTool[uid].tool1 = parseInt(battle.useTool[uid].tool1) + 1;
						else if(index == 2) battle.useTool[uid].tool2 = parseInt(battle.useTool[uid].tool2) + 1;
					}
				}
			}
			//减掉库存
			var pool = common.getPool();
			pool.getConnection(function (err, conn) {
				if (err) {
					console.log("POOL ==> " + err);
					return;
				}
				var sql = "UPDATE answer_user SET tool1=? WHERE id=?";
				if(index == 2) sql = "UPDATE answer_user SET tool2=? WHERE id=?";
				else if(index == 3) sql = "UPDATE answer_user SET tool3=? WHERE id=?";
				conn.query(sql, [data.count-1,uid],function(error, result) {
					if(error) {
						console.log(error);
						return;
					}
				});
				conn.release();
			});
		}
    });
	socket.on('loadPkInfo', function (uid) { //加载天梯玩家是否有未完成的比赛
		var bo = false;
		bbq:
		for(var i in battles) {
			var battle = battles[i];
			for(var id in battle.players) {
				if(uid == id) {
					if(battle.status == 5) break bbq; 
					bo = true;
					socket.emit('loadPkInfo', i);
					break bbq; 
				}
			}
		}
		if(!bo) socket.emit('loadPkInfo', 0);
    });
	
	socket.on('begin', function (room) { //处理裁判:拉取质疑列表
		if(typeof(games[room]) != "undefined") {
			games[room].begin = true;
			io.sockets.in('admin'+room).emit('begin',1);
			socket.broadcast.in(room).emit('next', 1);
		}
    });
	socket.on('loadBlackList', function (room) { //处理裁判:拉取黑名单
		if(typeof(games[room]) != "undefined") {
			socket.emit('loadBlackList',games[room].blackList);
		}
    });
	socket.on('loadQuery', function (room) { //处理裁判:拉取质疑列表
		if(typeof(games[room]) != "undefined" && games[room].allow == 0) {
			socket.emit('loadQuery', games[room].queries);
		}
    });
	socket.on('choose_classify',function (data) { //处理天梯比赛者的指令:选择题类
		var id = data.id;
		var uid = data.uid;
		var choose = data.choose;
		var battle = battles[id];
		if (!battle) return;
		if(battle.gameClassifies.length >= 2) return;
		var bo = true;
		for(var i in battle.gameClassifies) {
			if(battle.gameClassifies[i] == choose) {
				bo = false;
				break;
			}
		}
		if(bo) {
			battle.gameClassifies.push(choose);
			for(var i in battle.players) {
				if(typeof(ladders[i]) != "undefined") //通知玩家开始指令	
					io.sockets.connected[ladders[i].socketId].emit('choose_result',{uid:uid,choose:choose});
			//	else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
			}
		}
	});
	socket.on('ladders_answer',function (data) { //处理天梯比赛者的指令:回答问题
		var id = data.id;
		var uid = data.uid;
		var result = data.result;
		var battle = battles[id];
		if (!battle) return;
		var q = battle.questions[battle.currentIndex-1];
		var bo = parseInt(q.result) == parseInt(result);
		var point = battle.players[uid].point;
		if(bo && typeof(battle.answers[uid]) == "undefined") { //答对则加分
			var a = Math.floor(battle.seconds / 2);
			point = point + (20-a);
			battle.players[uid].point = point;
			//判断是否加入已答列表
			if(typeof(playerData[uid]) != "undefined") {
				if(typeof(playerData[uid][q.classifyID]) != "undefined") {
					var flag = true;
					for(var i in playerData[uid][q.classifyID]) {
						var row = playerData[uid][q.classifyID][i];
						if(row == q.id) {
							flag = false;
							break;
						}
					}
					if(flag) playerData[uid][q.classifyID].push(q.id);
				} else {
					playerData[uid][q.classifyID] = [q.id];
				}
			} else {
				playerData[uid] = {};
				playerData[uid][q.classifyID] = [q.id];
			}
		}
		battle.answers[uid] = result;
		for(var i in battle.players) {
			if(typeof(ladders[i]) != "undefined")
				io.sockets.connected[ladders[i].socketId].emit('ladders_answer',{uid:uid,result:bo,answer:result,point:point});
		//	else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
		}
	});
	socket.on('answer',function (data) { //处理比赛者的指令:回答问题
		var room = data.room;
		var name = data.name;
		var result = data.result;
		if (!games[room]) {
			socket.emit('answer', {name:name,result:0,answer:result});
			return;
		}
		var bo = games[room].questions[games[room].currentIndex].result == result;
		games[room].answers[name] = result;
		if(bo) {
			var point = games[room].points[name] + 10;
			connectionList[socketId].point = point;
			games[room].points[name] = point;
			io.sockets.in(room).emit('point',{name:name,point:point});
			io.sockets.in('admin'+room).emit('point',{name:name,point:point});
		}
		var index = games[room].currentIndex;
	//	console.log(index+":"+games[room].questions[index].result+":"+result);
		if(games[room].questions[games[room].currentIndex].result == result) {
			io.sockets.in(room).emit('answer', {name:name,result:1,answer:result});
			io.sockets.in('admin'+room).emit('answer', {name:name,result:1,answer:result});
		} else {
			io.sockets.in(room).emit('answer', {name:name,result:0,answer:result});
			io.sockets.in('admin'+room).emit('answer', {name:name,result:0,answer:result});
		}
	});
	socket.on('changeHead',function (data) { //处理比赛者的指令:修改头像
		var name = data.name;
		var room = data.room;
		var head = data.head;
		if(typeof(rooms[room]) != "undefined") {
			  var list = rooms[room];
			  for (var i in list) {
				  var socketId = list[i];
				  if(typeof(connectionList[socketId]) == "undefined") {
					  continue;
				  }
				  if(connectionList[socketId].role != 'admin' && connectionList[socketId].name == name) {
						connectionList[socketId].head = head;
						io.sockets.in(room).emit('changeHead', {name:name,head:head});
						io.sockets.in('admin'+room).emit('changeHead', {name:name,head:head});
						break;
				  }
			  }
		}
	});
	
	socket.on('disconnect', function () {
		var log = require("./log").logger("index");
		log.info('a connection was disconnect:'+socketId);
	//	console.log('a connection was disconnect:'+socketId);
		var role;
		if(typeof(connectionList[socketId]) != "undefined") {
			role = connectionList[socketId].role == 'admin'?"裁判":"参赛者";
			var room = connectionList[socketId].room;
		//	if(room) console.log(role+" "+connectionList[socketId].name+" 离开了房间 "+room);
			if(role == '参赛者' && room) {
				socket.broadcast.in(room).emit('leave' ,{name:connectionList[socketId].name,socketId:socketId});//通知本房间的其他用户自己离开了房间
				io.sockets.in('admin'+room).emit('leave' ,{name:connectionList[socketId].name,socketId:socketId});
				if(typeof(rooms[room]) != "undefined") {
					var index = rooms[room].indexOf(socketId);
					if (index !== -1) {
						rooms[room].splice(index, 1);
					}
				}
			}
		} else return;
		if(room) {
			if(role == '裁判') socket.leave("admin"+room);
			else socket.leave(room);
		}
		else {
			if(typeof(connectionList[socketId]) != "undefined" && typeof(connectionList[socketId].id) != "undefined") {
				if(connectionList[socketId].role == 'admin') socket.leave('admin');
				else socket.leave('ladder');
		//		console.log(connectionList[socketId].name+" "+" 断开了天梯房间");
				delete ladders[connectionList[socketId].id];
			}
		}
	//	if (connectionList[socketId].username) {
	//		socket.broadcast.emit('broadcast_quit', {
	//			username: connectionList[socketId].username
	//		});
	//	}
		delete connectionList[socketId];
	});
});
global.sockets = io.sockets;
global.rooms = rooms;
global.games = games;
global.searchingPlayers = searchingPlayers;
global.ladders = ladders;
global.battles = battles;
global.connectionList = connectionList;
global.playerData = playerData;
exports.listen = function (_server) {
    return io.listen(_server);
};
exports.instance = io;

/* 老天梯匹配规则
if(battle.status == 0) {//判断题目是否已经抽取成功,可以通知玩家开始比赛
if(battle.questions.length >= 10) {
	for(var i in battle.players) {
		if(typeof(ladders[i]) != "undefined") //通知玩家开始指令	
			io.sockets.connected[ladders[i].socketId].emit('news',{type:2,msg:id});
		else console.log("天梯房间 "+id+"玩家"+battle.players[i].name+"已短线");
	}
	battle.status = 1;
	console.log("天梯房间 "+id+"题目已经加载完毕,可以开始比赛");
}
} else if(battle.status == 1) { //收集玩家的准备指令,可以开始比赛
 var size = common.arraySize(battle.ready);
 console.log('判断ready:'+size);
 if(size == 0) continue;
 if(size >= 2) {
	battle.status = 2;
	battle.seconds = 0;
	continue;
 } else {
	battle.seconds++;
	if(battle.seconds == 10) {
		battle.status = 2;
		battle.seconds = 0;
		continue;
	}
 }
}
*/